<template>
  <div class="app-container cell">
    <div style="height: calc(100vh - 135px);user-select:none;">
      <vxe-grid ref="xGrid" v-bind="gridOptions" :cell-class-name="cellClassName" @form-reset="resetList" @edit-closed="editClosedEvent" @cell-click="cellClickEvent">
        <template #top>
          <div v-show="gridOptions.data.length>0&&selectedButton !== 'setThird'" style="text-align: right;">提示：双击进入行内编辑状态，单击空白处退出行内编辑状态</div>
        </template>
        <template #node_item="{ data }">
          <el-select v-model="data.node" transfer placeholder="项目进度" class="filter-item" @change="changeNode">
            <el-option v-for="item in dict.standard_process_node" :key="item.value" :value="item.value" :label="item.label" />
          </el-select>
        </template>
        <template #discipline_item="{ data }">
          <el-select v-model="data.discipline" transfer placeholder="专业" class="filter-item" @change="changeDiscipline">
            <el-option v-for="item in dict.standard_drawing_discipline" :key="item.value" :value="item.value" :label="item.label" />
          </el-select>
        </template>
        <template #operate_item>
          <vxe-button icon="el-icon-refresh-left" type="reset" size="medium" content="重置" style="margin-left:1px;" />
          <vxe-button icon="el-icon-tickets" size="medium" content="日志" plain @click="toggleShowLog" />
          <vxe-button icon="vxe-icon-warnion-circle-fill" size="medium" content="新增数据提示" plain @click="openDataTips" />
          <template v-if="selectedButton === 'setThird'">
            <vxe-button status="primary" size="medium" content="保存" @click="handleSave" />
            <vxe-button size="medium" content="取消" @click="handleCancel" />
          </template>
        </template>
        <template #extra_operate_item>
          <div v-show="showButton">
            <el-button-group v-if="selectedButton !== 'setThird'" style="margin-right: 10px;">
              <template v-for="button in buttonsFirstGroup">
                <el-button :key="button.key" type="primary" :plain="selectedButton === button.key ? false : true" @click="button.handler">{{ button.label }}</el-button>
              </template>
            </el-button-group>
            <el-button-group v-if="selectedButton !== 'setThird'">
              <template v-for="button in buttonsSecondGroup">
                <el-button :key="button.key" type="primary" :plain="selectedButton === button.key ? false : true" @click="button.handler">
                  {{ button.label }}
                </el-button>
              </template>
            </el-button-group>
          </div>
        </template>
        <template #gl_level_default="{ row }">
          <span>{{ row.levelGl }}</span>
        </template>
        <template #gl_level_edit="{ row }">
          <vxe-select v-model="row.levelGl" transfer @change="levelGlChangeEvent({ row })">
            <vxe-option v-for="item in dict.standard_component_model_depth" :key="item.value" :value="item.value" :label="item.label" />
          </vxe-select>
        </template>
        <template #gl_desc_edit="{ row }">
          <span>{{ row.glDesc }}</span>
        </template>
        <template #dl_level_default="{ row }">
          <span>{{ row.levelDl }}</span>
        </template>
        <template #dl_level_edit="{ row }">
          <vxe-select v-model="row.levelDl" transfer @change="levelDlChangeEvent({ row })">
            <vxe-option v-for="item in dict.standard_component_info_depth" :key="item.value" :value="item.value" :label="item.label" />
          </vxe-select>
        </template>
        <template #dl_desc_edit="{ row }">
          <span>{{ row.dlDesc }}</span>
        </template>
        <template v-for="(item,index) in dynamicAttrMaps" #[item.slots.default]="{ row }">
          <div :key="index">
            <span>{{ formatStandard(row[item.field]) }}</span>
          </div>
        </template>
        <template v-for="(item,index) in dynamicAttrMaps" #[item.slots.edit]="{ row }">
          <div :key="index">
            <vxe-select v-model="row[item.field]" transfer>
              <vxe-option v-for="item2 in fieldStandardsList" :key="item2.value" :value="item2.value" :label="item2.label" />
            </vxe-select>
          </div>
        </template>
      </vxe-grid>
      <!--查看设置排除项、设置必做项-->
      <el-dialog class="set_dialog" view convert-record :before-close="handleDialogClose" :title="dialogTitle" :visible.sync="showSet" :destroy-on-close="false">
        <Set ref="set" :show-set.sync="showSet" :node="gridOptions.formConfig.data.node" :discipline="gridOptions.formConfig.data.discipline" @init="init" />
      </el-dialog>
      <!-- 日志 -->
      <LogDialog :log-type="logType" :dialog-visible.sync="showLog" />
      <!-- 拖拽新增数据提示 -->
      <vue-drag-resize v-if="showTips" :x="250" :y="200" :w="1000" :h="600" :z="999" style="background-color: #fffdfd;" :parent-limitation="true">
        <div class="tip-main">
          <el-row>
            <div class="el-dialog__header"><span class="el-dialog__title">新增数据提示</span><button type="button" aria-label="Close" class="el-dialog__headerbtn"><i class="el-dialog__close el-icon el-icon-close" @click="closeModalTips" /></button></div>
          </el-row>
          <el-table ref="table" stripe :max-height="540" :data="dataTip" size="small" style="width: 100%;padding:20px;">
            <el-table-column prop="createTime" label="创建时间" />
            <el-table-column prop="typeName" label="构件大类、图纸专业" />
            <el-table-column prop="element" label="构件/元素、视图/模型/图纸类别" min-width="100" />
            <el-table-column prop="operationType" label="操作" />
            <el-table-column prop="nickName" label="操作人" />
          </el-table>
        </div>
      </vue-drag-resize>
    </div>
  </div>
</template>
<script>

import { queryDynamicRelationData, queryByComponentLevel, updateStandardRelationItem, queryBaseConfigItems, queryComponentDrawingLog, submitStandardRelationUnitConfig, queryByParam } from '@/api/modelQuality/nodeManage'
import Set from './set'
import LogDialog from '@/components/logManage/dialog'
import { NODE_LOG } from '@/utils/log'
export default {
  name: 'NodeManage',
  dicts: ['standard_process_node', 'standard_drawing_discipline', 'standard_component_model_depth', 'standard_component_info_depth'],
  components: { Set, LogDialog },
  data() {
    return {
      selectedCells: [], // 记录所有选中的单元格 淡蓝色
      cellRequiredList: [], // 必做单元格
      showTips: false, // 显示新增数据提示弹框
      dataTip: [], // 新增数据提示表格
      showButton: false, // 是否显示六个按钮
      dialogTitle: '', // 标题
      showSet: false, // 排除项和必做项弹框显示
      originalData: [], // 初始时为空，在组件加载时填充所有原始数据
      isFilteringRows: false, // 初始时没有过滤行
      requiredComponentIds: [], // 构件必选项
      requiredFields: [], // 图纸必选项
      exclusionComponentIds: [], // 构件排除项
      exclusionFields: [], // 图纸排除项
      selectedButton: 'all', // 初始化高亮
      buttonsFirstGroup: [
        { key: 'setSecond', label: '设置排除项', handler: () => this.handleSetItem(2, '设置排除项') },
        { key: 'setFirst', label: '设置必做项', handler: () => this.handleSetItem(1, '设置必做项') },
        { key: 'setThird', label: '设置必做单元格', handler: this.handleRequiredCell }
      ],
      buttonsSecondGroup: [
        { key: 'all', label: '显示全部', handler: this.showAllColumns },
        { key: 'hideExcluded', label: '隐藏排除项', handler: this.hideExcluded },
        { key: 'showExcluded', label: '仅显示排除项', handler: this.showExcluded },
        { key: 'showRequired', label: '仅显示必做项', handler: this.showRequired }
      ],
      dynamicAttrMaps: [],
      loading: false,
      fieldStandardsList: [
        { label: '√', value: 1 },
        { label: '○', value: 2 },
        { label: '-', value: 3 }
      ], // 分值数组
      gridOptions: {
        border: true,
        resizable: true,
        rowId: 'id',
        treeConfig: {
          transform: true,
          rowField: 'id',
          parentField: 'parentId'
        },
        height: 'auto', // 高度自适应
        rowConfig: { isCurrent: true, isHover: true },
        spanMethod: this.mergeRowMethod,
        formConfig: {
          data: {
            node: '',
            discipline: ''
          },
          items: [
            { field: 'node', slots: { default: 'node_item' }},
            { field: 'discipline', slots: { default: 'discipline_item' }},
            { slots: { default: 'operate_item' }},
            { slots: { default: 'extra_operate_item' }}
          ]
        },
        toolbarConfig: {
          custom: {
            icon: 'el-icon-s-grid'
          }
        },
        columns: [],
        data: [],
        keepSource: true,
        editConfig: {
          trigger: 'dblclick',
          mode: 'row',
          showIcon: false,
          icon: 'vxe-icon-edit',
          beforeEditMethod: ({ row, column }) => this.selectedButton !== 'setThird'
        }
      },
      showLog: false,
      logType: NODE_LOG
    }
  },
  methods: {
    // 通用行合并函数（将相同多列数据合并为一行）
    mergeRowMethod({ row, _rowIndex, column, visibleData }) {
      const fields = ['categoryName']
      const cellValue = row[column.property]
      if (cellValue && fields.includes(column.property)) {
        const prevRow = visibleData[_rowIndex - 1]
        let nextRow = visibleData[_rowIndex + 1]
        if (prevRow && prevRow[column.property] === cellValue) {
          return { rowspan: 0, colspan: 0 }
        } else {
          let countRowspan = 1
          while (nextRow && nextRow[column.property] === cellValue) {
            nextRow = visibleData[++countRowspan + _rowIndex]
          }
          if (countRowspan > 1) {
            return { rowspan: countRowspan, colspan: 1 }
          }
        }
      }
    },
    // 格式化交付物标准(1:✔,2:⚪,3:-)
    formatStandard(rowData) {
      let x = null
      switch (rowData) {
        case 1:x = '√'
          break
        case 2:x = '○'
          break
        case 3:x = '-'
          break
        default:
          x = rowData
      }
      return x
    },
    // 格式化交付物标准(1:✔,2:⚪,3:-)
    formatStandard2(rowData) {
      let x = null
      switch (rowData) {
        case '√':x = 1
          break
        case '○':x = 2
          break
        case '-':x = 3
          break
        default:
          x = rowData
      }
      return x
    },
    // 设置排除项 必做项
    handleSetItem(type, dialogTitle) {
      this.dialogTitle = dialogTitle
      this.showSet = true
      this.$nextTick(() => {
        if (this.$refs.set) {
          if (type === 1) {
            this.selectedButton = 'setFirst'
          } else {
            this.selectedButton = 'setSecond'
          }
          // 构件管理 type: 1必选项 2排除项
          this.$refs.set.queryRelationComponentGroups(type)
          // 图纸管理
          this.$refs.set.queryRelationDrawingGroups(type)
        }
      })
    },
    // 关闭弹框
    handleDialogClose() {
      this.showSet = false
      this.findList()
    },
    init() {
      this.selectedCells = []
      this.findList()
      this.queryBaseConfigItemsAndQueryByParam()
    },
    // 切换节点
    changeNode() {
      this.init()
    },
    // 切换专业
    changeDiscipline() {
      this.init()
    },
    // 标记排除项（❌）标记必做项（锁）+ 查询单元格里的必做项
    queryBaseConfigItemsAndQueryByParam() {
      if (this.gridOptions.formConfig.data.node && this.gridOptions.formConfig.data.discipline) {
        const params = {
          node: this.gridOptions.formConfig.data.node,
          standardDiscipline: this.gridOptions.formConfig.data.discipline
        }
        Promise.all([
          queryByParam(params),
          queryBaseConfigItems(params)
        ]).then(([queryByParamResponse, queryBaseConfigItemsResponse]) => {
          // 必做项单元格
          this.cellRequiredList = queryByParamResponse
          // 构件必选项
          this.requiredComponentIds = queryBaseConfigItemsResponse.requiredComponentIds
          // 构件排除项
          this.exclusionComponentIds = queryBaseConfigItemsResponse.exclusionComponentIds
          // 图纸必选项
          this.requiredFields = queryBaseConfigItemsResponse.requiredFields
          // 图纸排除项
          this.exclusionFields = queryBaseConfigItemsResponse.exclusionFields
        })
      }
    },
    // 获取动态列图标 图纸必选+排除
    getDynamicColumnIcon(item) {
      // 检查是否存在排除项
      if (this.exclusionFields.includes(item.field)) {
        return 'vxe-icon-error-circle-fill' // 标记排除项icon
      }
      // 检查是否存在必做项
      if (this.requiredFields.includes(item.field)) {
        return 'vxe-icon-lock-fill' // 标记必做项icon
      }
      return item.field
    },
    // 获取表格数据
    findList() {
      const _this = this
      const { gridOptions } = this
      setTimeout(() => {
        if (gridOptions.formConfig.data.node && gridOptions.formConfig.data.discipline) {
          gridOptions.loading = true
          // 获取列表
          const params = {
            appType: appType, // 管理
            isLock: false,
            node: gridOptions.formConfig.data.node,
            discipline: gridOptions.formConfig.data.discipline
          }
          queryDynamicRelationData(params).then(obj => {
            if (obj) {
              const dynamicDataSet = obj.dynamicDataSet
              for (let i = 0; i < dynamicDataSet.length; i++) {
                for (const item2 in obj.dynamicDataSet[i]) {
                  if (item2.substring(0, 5) === 'field') {
                    obj.dynamicDataSet[i][item2] = _this.formatStandard(obj.dynamicDataSet[i][item2])
                  }
                }
              }
              gridOptions.data = dynamicDataSet
              this.showButton = true
              this.selectedButton = 'all'
              this.originalData = [...gridOptions.data] // 复制一份原始数据
              this.dynamicAttrMaps = obj.dynamicAttrMaps.map(item => {
                return Object.assign(item, {
                  minWidth: 100,
                  editRender: {},
                  titlePrefix: {
                    icon: this.getDynamicColumnIcon(item)
                  }, // 标题前缀图标配置项
                  slots: { default: item.field + '_default', edit: item.field + '_edit' }
                })
              })
              gridOptions.columns = [
                { field: 'categoryName', title: '构件大类', width: 110, fixed: 'left', verticalAlign: 'top' },
                { field: 'componentName',
                  title: '构件/元素',
                  width: 100,
                  fixed: 'left',
                  slots: {
                    default: ({ row }) => {
                      if (this.exclusionComponentIds.length > 0 && this.exclusionComponentIds.includes(row.id)) {
                        return (
                          <div><vxe-icon name='error-circle-fill'></vxe-icon>{row.componentName}</div> // 标记排除项icon
                        )
                      }
                      if (this.requiredComponentIds.length > 0 && this.requiredComponentIds.includes(row.id)) {
                        return (
                          <div><vxe-icon name='lock-fill'></vxe-icon>{row.componentName}</div> // 标记必做项icon
                        )
                      }
                      return row.componentName
                    }
                  }
                },
                {
                  title: '模型深度',
                  fixed: 'left',
                  children: [
                    { field: 'levelGl', title: 'GL等级', width: 90, editRender: {}, slots: { default: 'gl_level_default', edit: 'gl_level_edit' }},
                    { field: 'glDesc', title: '说明', width: 240, editRender: {}, slots: { edit: 'gl_desc_edit' }}
                  ]
                },
                {
                  title: '信息深度',
                  fixed: 'left',
                  children: [
                    { field: 'levelDl', title: 'DL等级', width: 90, editRender: {}, slots: { default: 'dl_level_default', edit: 'dl_level_edit' }},
                    { field: 'dlDesc', title: '说明', width: 240, editRender: {}, slots: { edit: 'dl_desc_edit' }}
                  ]
                },
                {
                  title: '视图/模型/图纸类别',
                  children: this.dynamicAttrMaps
                }]
              gridOptions.loading = false
            } else {
              this.gridOptions.data = []
              this.gridOptions.columns = []
              gridOptions.loading = false
            }
          })
        }
      }, 500)
    },
    // 重置
    resetList() {
      this.gridOptions.formConfig.data = {
        node: '',
        discipline: ''
      }
      this.gridOptions.data = []
      this.gridOptions.columns = []
      this.gridOptions.loading = false
      this.showButton = false
      this.selectedButton = 'all'
      this.selectedCells = []
    },
    // 切换GL
    levelGlChangeEvent({ row }) {
      // 类型切换时更新级联的下拉数据
      const params = {
        componentId: row.id,
        level: row.levelGl
      }
      queryByComponentLevel(params).then(data => {
        if (data) {
          row.glDesc = data.description
        }
      })
    },
    // 切换DL
    levelDlChangeEvent({ row }) {
      // 类型切换时更新级联的下拉数据
      const params = {
        componentId: row.id,
        level: row.levelDl
      }
      queryByComponentLevel(params).then(data => {
        if (data) {
          row.dlDesc = data.description
        }
      })
    },
    editClosedEvent({ row, column }) {
      const $table = this.$refs.xGrid
      const field = column.property
      // 判断单元格值是否被修改
      if ($table.isUpdateByRow(row, field)) {
        const params = {
          node: row.node, // 节点
          standardDiscipline: row.discipline, // 专业
          category: row.category, // 种类
          componentId: row.id, // 组件id
          levelGL: row.levelGl, // GL等级
          levelDL: row.levelDl// DL等级
        }
        const fieldStandards = []
        for (const propertyName in row) {
          if (propertyName.substring(0, 5) === 'field') {
            fieldStandards.push(propertyName + '-' + this.formatStandard2(row[propertyName]))
          }
        }
        params.fieldStandards = fieldStandards // ['field25-3', 'field26-3', 'field27-3', 'field28-3'] // 动态列-分值
        updateStandardRelationItem(params).then(data => {
          setTimeout(() => {
            this.$notify({
              title: '修改成功',
              type: 'success',
              duration: 2500
            })
            // 局部更新单元格为已保存状态
            $table.reloadRow(row, null, field)
            this.init()
          }, 300)
        })
      }
    },
    // 显示全部
    showAllColumns() {
      // 显示所有列
      this.$refs.xGrid.resetColumn()
      // 显示所有行
      this.gridOptions.data = this.originalData
      this.selectedButton = 'all'
    },
    // 封装过滤行
    filterRows(idsToShow) {
      this.gridOptions.data = this.originalData.filter(row => idsToShow.includes(row.id))
    },
    // 封装显示隐藏列
    toggleColumnVisibility(column, visible) {
      if (column) {
        if (visible) {
          this.$refs.xGrid.showColumn(column)
        } else {
          this.$refs.xGrid.hideColumn(column)
        }
      }
    },
    // 隐藏排除项(隐藏❌行❌列，其余显示)
    hideExcluded() {
      this.selectedButton = 'hideExcluded'
      // 首先显示所有动态列
      this.dynamicAttrMaps.forEach(item => {
        const column = this.$refs.xGrid.getColumnByField(item.field)
        this.toggleColumnVisibility(column, true)
      })
      // 隐藏指定排除项列
      this.exclusionFields.forEach(field => {
        const column = this.$refs.xGrid.getColumnByField(field)
        this.toggleColumnVisibility(column, false)
      })
      // 隐藏指定排除项行
      this.gridOptions.data = this.originalData.filter(row => {
        return !this.exclusionComponentIds.includes(row.id)
      })
    },
    // 仅显示排除项
    showExcluded() {
      this.selectedButton = 'showExcluded'
      // 获取所有动态列的字段名
      const dynamicFieldNames = this.dynamicAttrMaps.map(item => item.field)
      // 首先隐藏所有动态列
      this.$refs.xGrid.getColumns().forEach(column => {
        if (dynamicFieldNames.includes(column.field)) {
          this.$refs.xGrid.hideColumn(column)
        }
      })
      // 显示指定的排除项列
      this.exclusionFields.forEach(field => {
        const column = this.$refs.xGrid.getColumnByField(field)
        this.toggleColumnVisibility(column, true)
      })
      // 过滤表格数据，只保留排除项行
      this.filterRows(this.exclusionComponentIds)
    },
    // 仅显示必做项
    showRequired() {
      this.selectedButton = 'showRequired'
      // 获取所有动态列的字段名
      const dynamicFieldNames = this.dynamicAttrMaps.map(item => item.field)
      // 首先隐藏所有动态列
      this.$refs.xGrid.getColumns().forEach(column => {
        if (dynamicFieldNames.includes(column.field)) {
          this.$refs.xGrid.hideColumn(column)
        }
      })
      // 显示必做项列
      this.requiredFields.forEach(field => {
        const column = this.$refs.xGrid.getColumnByField(field)
        this.toggleColumnVisibility(column, true)
      })
      // 过滤表格数据，只保留必做项行
      this.filterRows(this.requiredComponentIds)
    },
    // 日志弹框
    toggleShowLog() {
      this.showLog = !this.showLog
    },
    // 获取新增数据提示表格数据
    queryComponentDrawingLog() {
      queryComponentDrawingLog().then(res => {
        this.dataTip = res
      })
    },
    // 打开新增数据提示弹框
    openDataTips() {
      this.showTips = true
      this.queryComponentDrawingLog()
    },
    // 关闭新增数据提示弹框
    closeModalTips() {
      this.showTips = false
    },
    // 设置必做单元格
    handleRequiredCell() {
      this.selectedButton = 'setThird'
    },
    // 动态为单元格添加class
    cellClassName({ row, column }) {
      // 检查当前单元格是否在选中的单元格列表中
      const isSelected = this.selectedCells.some(cell => cell.row === row && cell.field === column.property)
      const isSubmit = this.cellRequiredList.some(cell => cell.componentId === row.id && cell.field === column.property)
      // 如果选中的单元格同时是提交的单元格，且configId有值，则添加'col-lock'，否则不添加
      const isLocked = isSelected && isSubmit && this.selectedCells.some(cell => cell.configId)

      // 选中的单元格
      if (isSelected) {
        // 如果同时满足选中和提交，并且configId有值，返回'col-blue col-lock'，否则返回'col-blue'
        return isLocked ? 'col-blue col-lock' : 'col-blue'
      }
      // 提交的单元格
      if (isSubmit) {
        return 'col-lock'
      }
      return null
    },
    // 点击单元格
    cellClickEvent({ row, column }) {
      // 只允许点击"视图/模型/图纸类别"下的动态列 且不是'-'的标识符 且点击了"必做单元格"
      const field = column.property
      if (field.substring(0, 5) === 'field' && row[field] !== '-' && row[field] !== 3 && this.selectedButton === 'setThird') {
        // 检查当前单元格是否已经选中
        const index = this.selectedCells.findIndex(cell => cell.row === row && cell.field === field)
        // 检查是否是必做单元格
        const requiredCell = this.cellRequiredList.find(cell => cell.componentId === row.id && cell.field === field)

        if (index !== -1) {
          // 如果当前单元格已经选中，则取消选中
          this.selectedCells.splice(index, 1)
        } else {
          // 如果当前单元格未选中，则添加到选中的单元格列表中
          this.selectedCells.push({
            row,
            field: field,
            componentId: row.id,
            node: this.gridOptions.formConfig.data.node,
            standardDiscipline: this.gridOptions.formConfig.data.discipline,
            configId: requiredCell ? requiredCell.configId : ''
          })
        }
      }
    },
    // 保存
    handleSave() {
      submitStandardRelationUnitConfig(this.selectedCells).then(() => {
        this.init()
      })
    },
    // 取消
    handleCancel() {
      this.selectedCells = []
      this.selectedButton = 'all'
    }
  }
}
</script>
<style scoped lang="scss">
  .tip-main{
    height: 100%;
    border: 1px solid #ccc;
  }
  ::v-deep .vxe-table .vxe-body--column.col-blue {
    background-color: rgba(0, 122, 255, 0.27);
  }
  ::v-deep .vxe-table .vxe-body--column.col-lock {
    position: relative;
    padding-left: 19px;
  }
  ::v-deep .vxe-table .vxe-body--column.col-lock::before {
    content: "";
    display: inline-block;
    background-image: url('../../../assets/images/lock.png');
    background-size: cover;
    width: 1em;
    height: 1em;
    position: absolute;
    left: 9px;
    top: 50%;
    transform: translateY(-50%);
  }
</style>
